﻿using System;
using System.ComponentModel;
using System.Linq.Expressions;

namespace MvvmBase.ViewModel
{
    public abstract class ViewModelBase : JobQueueViewModelBase
    {
        private readonly IDispatcherOwner _dispatcherOwner;
        private readonly INavigator _navigator;
        protected ViewModelBase(IDispatcherOwner dispatcherOwner, INavigator navigator)
        {
            _dispatcherOwner = dispatcherOwner;
            _navigator = navigator;
            SubmitOnJobCollectionChanged();
        }

        protected ViewModelBase()
        {
            if (!DesignerProperties.IsInDesignTool)
                throw new InvalidOperationException("This constructor only for designtime");
        }

        public event EventHandler<NavigatingFromEventArgs> NavigatingFrom
        {
            add
            {
                _navigator.NavigatingFrom += value;
            }
            remove
            {
                _navigator.NavigatingFrom -= value;
            }
        }
        public event EventHandler<NavigatingFromEventArgs> NavigatingBack
        {
            add
            {
                _navigator.NavigatingBack += value;
            }
            remove
            {
                _navigator.NavigatingBack -= value;
            }
        }
        public event EventHandler NavigatedBack
        {
            add
            {
                _navigator.NavigatedBack += value;
            }
            remove
            {
                _navigator.NavigatedBack -= value;
            }
        }
        public virtual void ExectuteIfCan(Action action)
        {
            _dispatcherOwner.ExectuteIfCan(action);
        }

        public virtual void Navigate(NavigationPlace navigationPlace, params object[] pars)
        {
            _navigator.Navigate(navigationPlace, pars);
        }


        public virtual void GoBack()
        {
            _navigator.GoBack();
        }

        protected override void RaisePropertyChanged<T>(Expression<Func<T>> propertyPath)
        {
            _dispatcherOwner.ExectuteIfCan(() => base.RaisePropertyChanged(propertyPath));
        }
    }
}